<template>
  <view v-show="node.visible" :class="{ 'dl-tree-node': true, 'is-hidden': !node.visible }" hover-stop-propagation="false">
    <view
      :class="{ content: true, 'is-leaf': isLeafNode }"
      hover-class="content-hover"
      hover-stop-propagation="false"
      @click="handleContentClick"
      :style="{ 'padding-left': `${node.level * gap}rpx` }"
    >
      <block v-if="isLeafNode">
        <image v-if="siblingIsNonLeaf && showLeafIcon" :style="{ width: `${2 * gap}rpx`, height: `${2 * gap}rpx` }" class="content-icon" :src="leafIcon" />
        <view v-else-if="siblingIsNonLeaf" :style="{ width: `${2 * gap}rpx`, height: `${2 * gap}rpx` }" class="content-icon"></view>
      </block>
      <image v-else :style="{ width: `${2 * gap}rpx`, height: `${2 * gap}rpx` }" class="content-icon" :src="parentIcon" />
      <view :class="{ 'content-name': true, 'left-border': isLeafNode && !siblingIsNonLeaf, 'is-end-leaf-node': isLeafNode && !siblingIsNonLeaf && isLastNode }">
        <view>
          <u-line :length="isLeafNode && !siblingIsNonLeaf ? `${gap * 2}rpx` : 0" color="#D8D8D8" />
          <image v-if="isLeafNode && !siblingIsNonLeaf && showLeafIcon" :style="{ width: `${2 * gap}rpx`, height: `${2 * gap}rpx` }" class="content-icon" :src="leafIcon" />
          <text>{{ node.data.name }}</text>
        </view>
        <view v-show="showCheckbox">
          <u-checkbox-group v-model="checked" iconPlacement="right" placement="row" iconSize="40rpx" @change="arr => hanldeContentCheck({ isChecking: arr.length > 0, node })">
            <u-checkbox :name="node.data.id" size="40rpx" iconSize="40rpx"> </u-checkbox>
          </u-checkbox-group>
        </view>
        <block v-if="isRadio">
          <view class="radio" :class="node.isRadio ? 'radio-checked' : ''" @tap="handeContentRadio(node.data.id)">
            <u-icon v-show="node.isRadio" name="checkbox-mark" color="#fff"></u-icon>
          </view>
        </block>
      </view>
    </view>
    <block v-if="!expand">
      <view v-if="childNodeRendered" v-show="expanded" class="children" hover-class="none" hover-stop-propagation="false">
        <tree-node v-for="(childNode, index) in node.childNodes" :key="index" :node="childNode" :isLastNode="index === node.childNodes.length - 1" />
      </view>
    </block>
    <block v-else>
      <tree-node v-for="(childNode, index) in node.childNodes" :key="index" :node="childNode" :isLastNode="index === node.childNodes.length - 1" />
    </block>
  </view>
</template>

<script>
import treeNode from './tree-node.vue'
import parentIcon from '@/static/images/work-order/tree-node.png'
import leafIcon from '@/static/images/work-order/worker.png'

export default {
  name: 'DlTreeNode',
  components: {
    treeNode
  },
  props: {
    node: {
      type: Object,
      default: () => {}
    },
    isLastNode: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    isLeafNode: function () {
      return this.node.isLeaf
    },
    expandEnable: function () {
      return !this.node.isLeaf
    },
    siblingIsNonLeaf: function () {
      return this.node.siblingIsNonLeaf
    },
    showLeafIcon: function () {
      return this.tree && this.tree.showLeafIcon
    },
    showCheckbox: function () {
      if (this.tree && this.tree.showCheckbox) {
        if (this.tree.treeNodeAllLeaf) return true
        const isLeaf = this.node.isLeaf
        if (this.tree.onlyCheckLeaf) {
          return isLeaf
        }
        if (this.tree.onlyCheckParent) {
          return !isLeaf
        }
        return true
      } else {
        return false
      }
    },
    isRadio: function () {
      return this.tree && this.tree.isRadio
    },
    expand: function () {
      return this.tree && this.tree.expand
    }
  },
  watch: {
    'node.checked': {
      immediate: true,
      handler: function (val) {
        this.checked = val
      }
    },
    // 子组件改变props,不激活watch
    'node.expanded': function (val) {
      this.$nextTick(() => (this.expanded = val))
      val && (this.childNodeRendered = true)
    }
  },
  data() {
    return {
      parentIcon,
      leafIcon,
      expanded: false,
      childNodeRendered: false,
      tree: null,
      gap: 30,
      radioValue: null,
      checked: []
    }
  },
  created() {
    this.currentNode = this.node
    const parent = this.$parent
    if (parent.isTree) {
      this.tree = parent
    } else {
      this.tree = parent.tree
    }
  },
  methods: {
    handleContentClick() {
      let clickNode = this.findTreeNodeById(this.tree.root.childNodes, this.node.data.id)
      this.expandEnable && this.handleNodeExpand(clickNode)
      this.showCheckbox && this.tree.checkedOnClickNode && this.handleNodeChecked(clickNode)
    },
    handleNodeExpand(clickNode) {
      if (this.tree.expand) return
      if (this.expanded) {
        clickNode.expanded = this.node.expanded = false
      } else {
        clickNode.expanded = this.node.expanded = true
      }
    },
    handleNodeChecked(node) {
      const isChecked = this.checked.length === 0
      this.checked = isChecked ? [node.data.id] : []
      this.hanldeContentCheck({ isChecking: isChecked, node })
    },
    hanldeContentCheck({ isChecking, node }) {
      if (this.tree.isSingleCheck) {
        const hasChecked = this.tree.checkedNodes[0]
        if (hasChecked) {
          this.node.checked = []
          // this.tree.checkedNodes.splice(1, 1)
          // this.tree.checkedNodes[0].checked = []
          // this.tree.updateCheckedNodes(hasChecked)
          // if (node.data.id !== hasChecked.data.id) {
          //   this.tree.checkedNodes.push(hasChecked)
          // }
        } else {
          this.checked = [node.data.id]
          this.tree.checkedNodes.push(node)
        }
      } else {
        if (isChecking) {
          this.tree.checkedNodes.push(node)
        } else {
          const index = this.tree.checkedNodes.findIndex(i => i.data.id === node.data.id)
          this.tree.checkedNodes.splice(index, 1)
        }
      }
      this.tree.$emit('check', { checkedNodes: this.tree.checkedNodes })
    },
    findTreeNodeById(childNodes, id) {
      let node = null
      for (let index = 0; index < childNodes.length; index++) {
        if (node) break
        const element = childNodes[index]
        if (element.data.id === id) {
          node = element
          break
        } else {
          node = this.findTreeNodeById(element.childNodes, id)
        }
      }
      return node
    },
    handeContentRadio(id) {
      this.setRadioChecked(this.tree.root.childNodes, id)
    },
    setRadioChecked(childNodes, id) {
      console.log(childNodes)
      for (let i = 0; i < childNodes.length; i++) {
        if (childNodes[i].data.id === id) {
          childNodes[i].isRadio = !childNodes[i].isRadio
          this.tree.$emit('checkRadio', { checkedNodes: !childNodes[i].isRadio ? null : childNodes[i] })
        } else {
          childNodes[i].isRadio = false
        }
        this.setRadioChecked(childNodes[i].childNodes, id)
      }
    }
  }
}
</script>

<style lang="scss">
.dl-tree-node {
  font-size: 32rpx;
  color: #333333;
  line-height: 40rpx;
  .content {
    display: flex;
    align-items: center;
    column-gap: 10rpx;
    padding-top: 17rpx;
    padding-bottom: 17rpx;
    padding-right: 20rpx;
    &.content-hover {
      background-color: #e4e4e4;
    }
    .content-name {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      > view:first-child {
        display: flex;
        align-items: center;
        column-gap: 8rpx;
      }
    }
    &.is-leaf {
      padding-top: 0;
      padding-bottom: 0;
      .content-name {
        padding-top: 24rpx;
        padding-bottom: 24rpx;
        &.left-border {
          position: relative;
          &::after {
            content: '';
            position: absolute;
            height: 100%;
            border-left: 1px solid #d8d8d8;
          }
          &.is-end-leaf-node {
            &::after {
              height: 50%;
              top: 0;
            }
          }
        }
      }
    }
    &-icon {
      display: block;
      flex-shrink: 0;
      &:not(image) {
        position: relative;
        &::after {
          position: absolute;
          display: block;
          content: '';
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 20rpx;
          height: 20rpx;
          border-radius: 4rpx;
          border: 2rpx solid $u-primary;
        }
      }
    }
  }
  .radio {
    width: 32rpx;
    height: 32rpx;
    background-color: #fff;
    border: 2rpx solid #c8c9cc;
    border-radius: 6rpx;
    display: block;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .radio-checked {
    background: #2979ff;
    font-size: 12rpx;
  }
}
</style>
